package validators

import (
	"errors"
	"reflect"

	"github.com/go-playground/locales/en"
	"github.com/go-playground/locales/zh"
	"github.com/go-playground/locales/zh_Hans_HK"
	ut "github.com/go-playground/universal-translator"
	"github.com/go-playground/validator/v10"
	en_translations "github.com/go-playground/validator/v10/translations/en"
	zh_translations "github.com/go-playground/validator/v10/translations/zh"
	zh_Hans_HK_translations "github.com/go-playground/validator/v10/translations/zh_tw"

	"hyper/lang"
)

/**
 * @description: 公用验证方法
 * @param {interface{}} structName 参数验证规则结构
 * @param {string} language 语言
 * @return {bool, string, error}, 验证是否通过, 错误信息, error
 */
func NewComValidator(structName interface{}, l string) error {

	// 同时加载多个语言包
	// zh_Hans_HK 中文繁体
	// zh 中文简体
	// en 英文
	uni := ut.New(zh.New(), zh_Hans_HK.New(), en.New())

	// 设置语言
	trans, _ := uni.GetTranslator(l)

	// 实例化验证类
	validate := validator.New()

	// 注册一个函数，获取struct tag里自定义的label作为字段名
	validate.RegisterTagNameFunc(func(fld reflect.StructField) string {
		// 从label中获取字段名
		name := lang.VField[fld.Name][l]
		return name
	})

	// 注册验证类与语言包
	err := switchRegLang(l, validate, trans)
	if err != nil {
		return errors.New("验证器验证语言包实例化错误")
	}

	// 验证数据
	validateErr := validate.Struct(structName)

	if validateErr != nil {
		errMsg := validateErr.(validator.ValidationErrors)[0]
		return errors.New(errMsg.Translate(trans))
	}

	return nil
}

/**
 * @description: 语言包字符串转换
 * @param l string 语系
 * @param validate 验证信息
 * @param trans     语言
 * @return errors
 */
func switchRegLang(l string, validate *validator.Validate, trans ut.Translator) error {
	switch l {
	case `zh`:
		return zh_translations.RegisterDefaultTranslations(validate, trans)
	case `en`:
		return en_translations.RegisterDefaultTranslations(validate, trans)
	case `zh_Hans_HK`:
		return zh_Hans_HK_translations.RegisterDefaultTranslations(validate, trans)
	default:
		return en_translations.RegisterDefaultTranslations(validate, trans)
	}
}
